package com.example.student.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.student.entity.SysMenu;
import com.example.student.entity.SysRole;
import com.example.student.entity.SysRoleMenu;
import com.example.student.exception.BusinessException;
import com.example.student.mapper.SysMenuMapper;
import com.example.student.mapper.SysRoleMapper;
import com.example.student.mapper.SysRoleMenuMapper;
import com.example.student.model.MenuVO;
import com.example.student.service.MenuService;
import com.example.student.util.SecurityUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class MenuServiceImpl implements MenuService {

    @Resource
    private SysMenuMapper menuMapper;
    
    @Resource
    private SysRoleMenuMapper roleMenuMapper;
    
    @Resource
    private SysRoleMapper roleMapper;

    @Override
    public List<MenuVO> getCurrentUserMenus() {
        List<SysMenu> menuList;
        
        // 获取用户ID
        Long userId = SecurityUtil.getUserId();
        if (userId == null) {
            return new ArrayList<>();
        }
        
        // 获取用户角色
        List<String> roles = SecurityUtil.getUserRoles();
        
        if (roles.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 检查是否为管理员
        boolean isAdmin = roles.stream()
                .anyMatch(role -> "ROLE_ADMIN".equals(role));
        
        if (isAdmin) {
            // 管理员获取所有启用状态的菜单
            menuList = menuMapper.selectList(
                    new LambdaQueryWrapper<SysMenu>()
                            .eq(SysMenu::getStatus, 1)
                            .orderByAsc(SysMenu::getSortOrder)
            );
        } else {
            // 普通用户获取有权限的启用状态菜单
            menuList = menuMapper.selectMenusByUserId(userId);
            // 过滤掉禁用状态的菜单
            menuList = menuList.stream()
                    .filter(menu -> menu.getStatus() == 1)
                    .collect(Collectors.toList());
        }
        
        // 转换为树形结构
        return buildMenuTree(menuList);
    }
    
    @Override
    public List<MenuVO> getUserNavMenus() {
        List<SysMenu> menuList;
        
        // 获取用户ID
        Long userId = SecurityUtil.getUserId();
        if (userId == null) {
            return new ArrayList<>();
        }
        
        // 获取用户角色
        List<String> roles = SecurityUtil.getUserRoles();
        if (roles.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 检查是否为管理员
        boolean isAdmin = roles.stream()
                .anyMatch(role -> "ROLE_ADMIN".equals(role));
        
        if (isAdmin) {
            // 管理员获取所有启用状态的目录和菜单
            menuList = menuMapper.selectList(
                    new LambdaQueryWrapper<SysMenu>()
                            .eq(SysMenu::getStatus, 1)
                            .in(SysMenu::getMenuType, 0, 1) // 只获取目录和菜单，不获取按钮
                            .orderByAsc(SysMenu::getSortOrder)
            );
        } else {
            // 普通用户获取有权限的启用状态目录和菜单
            menuList = menuMapper.selectMenusByUserId(userId);
            // 过滤掉禁用状态的菜单和按钮
            menuList = menuList.stream()
                    .filter(menu -> menu.getStatus() == 1 && (menu.getMenuType() == 0 || menu.getMenuType() == 1))
                    .collect(Collectors.toList());
        }
        
        // 转换为树形结构
        return buildMenuTree(menuList);
    }

    @Override
    public List<MenuVO> getAllMenus() {
        // 查询所有菜单
        List<SysMenu> menuList = menuMapper.selectList(
                new LambdaQueryWrapper<SysMenu>()
                        .orderByAsc(SysMenu::getSortOrder)
        );
        
        // 转换为树形结构
        return buildMenuTree(menuList);
    }
    
    @Override
    public List<MenuVO> getMenuTree() {
        // 查询所有菜单
        List<SysMenu> menuList = menuMapper.selectList(
                new LambdaQueryWrapper<SysMenu>()
                        .orderByAsc(SysMenu::getSortOrder)
        );
        
        // 转换为树形结构
        return buildMenuTree(menuList);
    }

    @Override
    public SysMenu getMenuById(Long id) {
        SysMenu menu = menuMapper.selectById(id);
        if (menu == null) {
            throw new BusinessException("菜单不存在");
        }
        return menu;
    }
    
    @Override
    public List<Long> getMenuIdsByRoleId(Long roleId) {
        return roleMenuMapper.selectList(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .eq(SysRoleMenu::getRoleId, roleId)
        ).stream().map(SysRoleMenu::getMenuId).collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addMenu(SysMenu menu) {
        // 检查父菜单是否存在
        if (menu.getParentId() != null && menu.getParentId() != 0) {
            SysMenu parentMenu = menuMapper.selectById(menu.getParentId());
            if (parentMenu == null) {
                throw new BusinessException("父菜单不存在");
            }
        }
        
        menuMapper.insert(menu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMenu(SysMenu menu) {
        // 检查菜单是否存在
        SysMenu existMenu = menuMapper.selectById(menu.getId());
        if (existMenu == null) {
            throw new BusinessException("菜单不存在");
        }
        
        // 检查父菜单是否存在
        if (menu.getParentId() != null && menu.getParentId() != 0) {
            SysMenu parentMenu = menuMapper.selectById(menu.getParentId());
            if (parentMenu == null) {
                throw new BusinessException("父菜单不存在");
            }
            
            // 不能将自己设为自己的父菜单
            if (menu.getId().equals(menu.getParentId())) {
                throw new BusinessException("不能将自己设为自己的父菜单");
            }
            
            // 不能将自己的子菜单设为自己的父菜单
            List<Long> childIds = getChildMenuIds(menu.getId());
            if (childIds.contains(menu.getParentId())) {
                throw new BusinessException("不能将自己的子菜单设为自己的父菜单");
            }
        }
        
        menuMapper.updateById(menu);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMenu(Long id) {
        // 检查菜单是否存在
        SysMenu menu = menuMapper.selectById(id);
        if (menu == null) {
            throw new BusinessException("菜单不存在");
        }
        
        // 检查是否有子菜单
        Long childCount = menuMapper.selectCount(
                new LambdaQueryWrapper<SysMenu>()
                        .eq(SysMenu::getParentId, id)
        );
        
        if (childCount > 0) {
            throw new BusinessException("存在子菜单，不能删除");
        }
        
        // 删除角色菜单关联
        roleMenuMapper.delete(
                new LambdaQueryWrapper<SysRoleMenu>()
                        .eq(SysRoleMenu::getMenuId, id)
        );
        
        // 删除菜单
        menuMapper.deleteById(id);
    }
    
    /**
     * 构建菜单树
     */
    private List<MenuVO> buildMenuTree(List<SysMenu> menuList) {
        // 转换为VO
        List<MenuVO> menuVOList = menuList.stream().map(menu -> {
            MenuVO vo = new MenuVO();
            vo.setId(menu.getId());
            vo.setParentId(menu.getParentId());
            vo.setName(menu.getMenuName());
            vo.setPath(menu.getMenuUrl());
            vo.setComponent(menu.getMenuUrl());
            vo.setIcon(menu.getIcon());
            vo.setOrderNum(menu.getSortOrder());
            vo.setType(menu.getMenuType());
            vo.setPermission(menu.getPermission());
            vo.setVisible(menu.getStatus());
            vo.setChildren(new ArrayList<>());
            return vo;
        }).collect(Collectors.toList());
        
        // 构建树形结构
        List<MenuVO> rootMenus = new ArrayList<>();
        for (MenuVO menu : menuVOList) {
            // 父菜单ID为0或null的为根菜单
            if (menu.getParentId() == null || menu.getParentId() == 0) {
                rootMenus.add(menu);
            }
        }
        
        // 递归设置子菜单
        for (MenuVO menu : rootMenus) {
            setChildren(menu, menuVOList);
        }
        
        // 按排序号排序
        rootMenus.sort(Comparator.comparing(MenuVO::getOrderNum));
        
        return rootMenus;
    }
    
    /**
     * 递归设置子菜单
     */
    private void setChildren(MenuVO menu, List<MenuVO> menuList) {
        List<MenuVO> children = new ArrayList<>();
        for (MenuVO item : menuList) {
            if (menu.getId().equals(item.getParentId())) {
                children.add(item);
                // 递归设置子菜单的子菜单
                setChildren(item, menuList);
            }
        }
        
        // 按排序号排序
        children.sort(Comparator.comparing(MenuVO::getOrderNum));
        menu.setChildren(children);
    }
    
    /**
     * 获取子菜单ID列表
     */
    private List<Long> getChildMenuIds(Long menuId) {
        List<Long> childIds = new ArrayList<>();
        List<SysMenu> childMenus = menuMapper.selectList(
                new LambdaQueryWrapper<SysMenu>()
                        .eq(SysMenu::getParentId, menuId)
        );
        
        for (SysMenu childMenu : childMenus) {
            childIds.add(childMenu.getId());
            childIds.addAll(getChildMenuIds(childMenu.getId()));
        }
        
        return childIds;
    }
} 